#!/usr/bin/env python

'''
This module implements the recording of video frames (jpegs) to disk and
logging them into the frame database.
'''

# built-in modules
import os
import sys
import tempfile
import time

# opencircuit modules
from eventmanager import EventManager
from videoframe import VideoFrame
from framedatabase import  FrameDatabase, Frame

class Recorder(EventManager):
    '''
    Implements a frame recorder.
    '''
    
    motion_detected = False
    
    def __init__(self, frame_grabber, storage_path, logfile, dbfile):
        '''
        Class initializer.
        '''
        events = ['motion-detected', 'frame-added']
        EventManager.__init__(self, events)
        self.frame_grabber = frame_grabber
        self.storage_path = storage_path
        self.framedb = FrameDatabase(dbfile)
        self.frame_grabber.connect('new-frame', self.record_frame)
        self.frame_grabber.connect('motion-detected', self.on_motion_detected)
        
    def record_frame(self, video_frame):
        '''
        Save frame to disk and add record to database.
        '''
        # seriously?  do this right
        ms = int(str(round(video_frame.timestamp, 4)).split('.')[1])
        timeobj = time.localtime(video_frame.timestamp)
        timestr = time.strftime('%d%m%Y_%H%M%S', timeobj)
        arcname = '%s-%s.jpg' % (timestr, ms)
        y = time.strftime('%Y', timeobj)
        m = time.strftime('%m', timeobj)
        d = time.strftime('%d', timeobj)
        dev = self.frame_grabber.device.replace('/dev/','')
        arcpath = os.path.join(self.storage_path, dev, y, m, d)
        if not os.path.isdir(arcpath): os.makedirs(arcpath)
        video_frame.image.save(os.path.join(arcpath, arcname),quality=80)
        frame = Frame(os.path.join(arcpath, arcname), dev, 
            timestamp=video_frame.timestamp, motion=self.motion_detected)
        self.framedb.add_frame(frame)
        self.emit('frame-added', video_frame.timestamp)
        self.motion_detected = False
    
    def on_motion_detected(self, value):
        #self.emit('motion-detected', value)
        self.motion_detected = True

        
#-------------------------------------------------------------------------------
# test script
if __name__ == '__main__':
    
    from framegrabber import FrameGrabber

    def on_frame_added(timestamp):
        sys.stdout.write('.')
        sys.stdout.flush()
    
    def on_motion_detected(value):
        sys.stdout.write('*')
        sys.stdout.flush()

    framerate = 1
    
    source = FrameGrabber(device='/dev/video0', size=(640,480), framerate=framerate)
    source.motion_detection = True

    tmp_path = os.path.join('/tmp', 'opencircuit')
    logfile = os.path.join(tmp_path, 'logfile.dat')
    dbfile = os.path.join(tmp_path, 'frames.db')
    
    if not os.path.isdir(tmp_path):
        os.makedirs(tmp_path)

    recorder = Recorder(source, storage_path=tmp_path, logfile=logfile, dbfile=dbfile)
    recorder.connect('frame-added', on_frame_added)
    recorder.connect('motion-detected', on_motion_detected)       

    print 'Starting to record in "%s"' % tmp_path
    sys.stdout.write('[')
    sys.stdout.flush()
    while True:
        try:
            time.sleep(0.1)
        except KeyboardInterrupt:
            source.stop()
            sys.stdout.write(']\n')
            sys.stdout.flush()
            sys.exit(0)
            
